""" FuzzyOperators
    
    
    
    2006 (C) Pollini Andrea

    this file si released under LGPL license 2.0  or above.
"""

__author__ = "Pollini Andrea  nelson1977@gmail.com"


import FuzzyVariable
import MembershipFunctions

  
class FuzzyStatement(object):
    """
        this class is an abstract class that describe a fuzzy statement.
        Given a FuzzyVariable
    """
    def __init__(self, aVariable, aMemberFunctionName):
        self.var = aVariable
        self.member_function = aMemberFunctionName
        
    def dof(self, aValue):
        pass
    
    
class Modifier(object):
    coeff = 1.0
    def __init__(self,aFuzzyStatement):
        self.statement = aFuzzyStatement
        #self.coeff = aCoeff
        
    def __call__(self, aValue):
        return self.statement(aValue) ** self.coeff
        
class Very(Modifier):
    coeff = 2.0
    
        
class IS(FuzzyStatement):
    def dof(self, aValue):        
        return self.var(aValue)[self.member_function]
    
    def __call__(self,aValue):
        return self.dof(aValue)
    
    def __str__(self):
        return "(%s IS %s)"% (self.var.name,self.member_function)
    
    
class ISNOT(FuzzyStatement):
    def dof(self, aValue):        
        return 1.0 - self.var(aValue)[self.member_function]    
    
    def __call__(self,aValue):
        return self.dof(aValue)   
 
    def __str__(self):
        return "(%s IS NOT %s)"% (self.var.name,self.member_function)

class FuzzyOperator:
    """
    
    """
    def __init__(self, function, str_rep=""):
        self.function = function
        self.str_rep = str_rep
    def __ror__(self, other):
        return FuzzyOperator(lambda x, self=self, other=other: self.function(other, x))
    def __or__(self, other):
        return self.function(other)
    def __rlshift__(self, other):
        return FuzzyOperator(lambda x, self=self, other=other: self.function(other, x))
    def __rshift__(self, other):
        return self.function(other)
    def __call__(self, value1, value2):
        return self.function(value1, value2) 
    def __str__(self):
        return self.str_rep
    
    
op_and = FuzzyOperator(lambda x,y: min(x,y),"AND")
op_and_dot = FuzzyOperator(lambda x,y: x * y,"AND")
#op_and _yager = FuzzyOperator(lambda x,y: 1-min([1, ]))

op_or_yager = FuzzyOperator(lambda x,y: max(x,y),"OR")
op_or = op_or_yager
    
    
if __name__ == '__main__':
    fv  = FuzzyVariable.FuzzyVariable("prova")
    fv.add(MembershipFunctions.make_membership_function("TRIANGULAR","basso",values=[0,1.2,2.5]))
    fv.add(MembershipFunctions.make_membership_function("TRIANGULAR","medio",values=[1,2.2,4.5]))
    fv.add(MembershipFunctions.make_membership_function("TRIANGULAR","alto",values=[2,4.2,5]))
    
    #print fv(1), fv(2),fv(3),fv(4),fv(5)    
    print IS(fv,"medio").dof(3)
    print IS(fv,"alto").dof(3)
    print IS(fv,"medio").dof(3) |op_and_dot| IS(fv,"alto").dof(3)
    print IS(fv,"medio")(3) |op_and| IS(fv,"alto")(3)
    print Very(IS(fv,"medio"))(3) |op_and| Very(IS(fv,"alto"))(3)